package com.sun.jdk8.parallel;

import org.junit.Test;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

/**
 * 需求：
 * 使用fork/join计算1-10000的和，当一个任务的计算数量大于3000的时候拆分任务，数量小于3000的时候计算
 */
public class ForkJoinDemo {
    
    @Test
    public void test01(){
        long start = System.currentTimeMillis();
        // 得到一个ForkJoin线程池
        ForkJoinPool pool = new ForkJoinPool();
        // 创建线程要执行的任务
        SumRecursiveTask task = new SumRecursiveTask(1,10000);
        Long result = pool.invoke(task);
        System.out.println("result="+result);
        long end = System.currentTimeMillis();
        System.out.println("总的耗时："+(end-start));
    }

    private class SumRecursiveTask extends RecursiveTask<Long> {

        // 定义一个拆分的临界值
        private static final long THRESHOLD = 3000L;
        private final long start;
        private final long end;
        
        public SumRecursiveTask(long start,long end){
            this.start = start;
            this.end = end;
        }
        /**
         * The main computation performed by this task.
         *
         * @return the result of the computation
         */
        @Override
        protected Long compute() {
            long length = end - start;
            if(length <= THRESHOLD){
                // 任务不用拆分，可以计算
                long sum = 0;
                for(long i=start;i<=end;i++){
                    sum += i;
                }
                System.out.println("计算："+start+"-->"+end+",的结果为："+sum);
                return sum;
            }else {
                // 数量大于预定的临界值，那说明任务还需要继续拆分
                long middle = (start+end)/2;
                System.out.println("拆分左边："+start+"-->"+middle+"，→右边："+(middle+1)+"-->"+end);
                SumRecursiveTask left = new SumRecursiveTask(start, middle);
                left.fork();//左边分治
                SumRecursiveTask right = new SumRecursiveTask(middle + 1, end);
                right.fork(); // 右边分治
                return left.join()+right.join(); // 左右两边分治完了之后，做归并操作
            }
        }
    }
}


